/*
 * xat_linux.c
 * KJ's simplified stream archiver (kjssar)
 * 
 * (C)Copyright 2013-2015 by Klaus-J. Wolf, kj (at) seismic (dot) de
 * This file is licensed under the General Public License Version 2.
 * http://www.gnu.org/licenses/gpl-2.0.html
 * 
 * This is a proof-of-concept implementation.
 * 
 */

#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <acl/libacl.h>
#include <sys/xattr.h>

#include "prelim.h"
#include "xat.h"


#define BUFSIZE 0x4000


uchar *kjssar_getxattr_f(uchar *ffn)
{
    int idlistsz, valsz;
    uchar *idlist = malloc(BUFSIZE);
    uchar *val;
    uchar *res;
    int i,p;
    
    MEMASSERT(idlist,NULL)
    idlistsz = llistxattr(ffn, idlist, BUFSIZE);
    if(idlistsz<0)
    {
        free(idlist);
        return NULL;
    }
    if(idlistsz==0)
    {
        free(idlist);
        return strdup("");  /* we don't check for NULL here, because that wouldn't change anything for now */
    }
    
    val = malloc(BUFSIZE);
    MEMASSERT(val,NULL)
    res = malloc(BUFSIZE);
    MEMASSERT(res,NULL)

    res[0]=0;
    while(p < idlistsz)
    {
        i = strlen(idlist+p);
        valsz = lgetxattr(ffn, idlist+p, val, BUFSIZE);
        if(concatentry(res, BUFSIZE, idlist+p, val, valsz))
        {
            free(idlist);
            free(val);
            free(res);
            return NULL;
        }
        p+=i+1;
    }
    return res;
}


uchar *kjssar_getacl_f(uchar *ffn)
{
    acl_t acl;
    uchar *res, *res2;
    
    acl = acl_get_file(ffn, ACL_TYPE_DEFAULT);
    /* IEEE Std 1003.1e draft 17 (“POSIX.1e”, abandoned) */
    if(acl==NULL)
        return NULL;
    res = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE);
    /* This is a non-portable, Linux specific extension to the ACL manipulation
       functions defined in IEEE Std 1003.1e draft 17 (“POSIX.1e”, abandoned). */
    acl_free(acl);
    if(res==NULL)
        return NULL;
    res2 = strdup(res);
    acl_free(res);
    return res2;
}


